﻿Imports System
Imports System.IO
Imports System.Text
Imports SevenZip

Public Class frmExtract

	' same directry with excute file.
	Private pathTo7zDll = Path.Combine(Application.StartupPath, "7z.dll")
	Private pathTo7zs = Path.Combine(Application.StartupPath, "SevenZipSharp.dll")

	Private extractFolder As String

	Private cmd As New Dictionary(Of String, Boolean)

	Private fYes As Boolean
	Private fNo As Boolean
	Private fYesAll As Boolean
	Private fNoAll As Boolean
	Private fCancel As Boolean

	Private hasError As Boolean = False

	'Private doCancel As Boolean
	'Private doOverWrite As Boolean

	Enum ExtractTo
		Desktop
		SameArchive
		AskEveryTime
		Specified
	End Enum

	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
		' check need dll then load
		Load_7zDll()

		If Environment.GetCommandLineArgs().Length > 1 Then
			Me.Show()
			My.Application.DoEvents()
			Analyze_CommandLine()
		Else
			Me.Hide()
			My.Application.DoEvents()
			frmOption.ShowDialog()
		End If
	End Sub

	Private Sub Analyze_CommandLine()
		Select Case Environment.GetCommandLineArgs(1)
			Case "-l"
			Case "--list"
				For i As Integer = 2 To Environment.GetCommandLineArgs().Length - 1
					dlgLogs.ListContents(Environment.GetCommandLineArgs(i))
				Next
				Me.Hide()
				My.Application.DoEvents()
				dlgLogs.ShowDialog()
				End
			Case "-d"
			Case "--decompress"
				For i As Integer = 2 To Environment.GetCommandLineArgs().Length - 1
					Extract(Environment.GetCommandLineArgs(i), extractFolder)
				Next
			Case Else
				For i As Integer = 1 To Environment.GetCommandLineArgs().Length - 1
					Extract(Environment.GetCommandLineArgs(i), extractFolder)
				Next
		End Select
	End Sub

	Public sze As SevenZipExtractor
	Public extractedFileCount As Integer

	''' <summary>
	''' 
	''' </summary>
	''' <param name="path_">arcive file</param>
	''' <param name="to_">extract to</param>
	''' <remarks></remarks>
	Public Sub Extract(ByVal path_ As String, ByVal to_ As String)
		If Not IO.File.Exists(path_) Then
			dlgLogs.lsbLogs.Items.Add("File not found: " & path_)
		End If

		Try
			sze = New SevenZipExtractor(path_)
		Catch ex As Exception
			MsgBox(ex.ToString, MsgBoxStyle.OkOnly, "Error")
			End
		End Try

		AddHandler sze.Extracting, AddressOf Extracting
'		AddHandler sze.FileExists, AddressOf FileExists
		AddHandler sze.FileExtractionStarted, AddressOf FileExtractionStarted
		AddHandler sze.FileExtractionFinished, AddressOf FileExtractionFinished
		'AddHandler sze.ExtractionFinished, AddressOf ExtractionFinished

		Select Case My.Settings.ExtractToIndex
			Case ExtractTo.SameArchive '// same arcive folder
				extractFolder = Path.GetDirectoryName(path_)
			Case ExtractTo.AskEveryTime	'// 展開時に指定
				If FolderBrowserDialog.ShowDialog = DialogResult.OK Then
					extractFolder = FolderBrowserDialog.SelectedPath
				Else
					Return
				End If
			Case ExtractTo.Specified
				extractFolder = My.Settings.ExtractFolder
			Case Else '// 既定でデスクトップに展開
				extractFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
		End Select

		'// create folder
		If My.Settings.ExtractCreateFolder Then
			extractFolder = Path.Combine(extractFolder, Path.GetFileNameWithoutExtension(path_))
			My.Computer.FileSystem.CreateDirectory(extractFolder)
		End If

		fNo = False
		fYesAll = False
		fNoAll = False

		lblArchive.Text = sze.FileName
		pgbArchive.Maximum = sze.FilesCount
		pgbArchive.Value = 0
		extractedFileCount = 0

		 Me.Text = "0% / " & sze.FileName

		sze.ExtractArchive(extractFolder)

		Me.WindowState = FormWindowState.Minimized
		Me.Visible = False
		'Me.ShowInTaskbar = False

		dlgLogs.Show()


		If My.Settings.OpenExtractFolder Then
			Process.Start(extractFolder)
		End If

	End Sub

	'Private e_PercentDone As Byte

	'Delegate Sub ExtractingDelegate()

	'Private Sub SetPercentDone()
	'    pgbExtract.Value = e_PercentDone
	'    My.Application.DoEvents()
	'End Sub

	'
	' Extracting
	'
	Private Sub Extracting(ByVal sender As Object, ByVal e As SevenZip.ProgressEventArgs)
		' canceled
		e.Cancel = fCancel

		pgbExtract.Value = e.PercentDone
		My.Application.DoEvents()
	End Sub

	Private Sub FileExtractionStarted(ByVal sender As Object, ByVal e As SevenZip.FileInfoEventArgs)
		e.Cancel = fCancel
		If fNo Then
			fNo = False
			dlgLogs.lsbLogs.Items.Add(e.FileInfo.FileName & " ... Not Extracted")
			Return
		End If
		'Me.Text = e.PercentDone & "% / " & lblArchive.Text
		lblExtract.Text = e.FileInfo.FileName
		My.Application.DoEvents()
	End Sub

	Private Sub FileExtractionFinished(ByVal sender As Object, ByVal e As SevenZip.FileInfoEventArgs)
		extractedFileCount += 1
		Me.Text = CInt(extractedFileCount / sze.FilesCount * 100) & "% / " & lblArchive.Text
		pgbArchive.Value = extractedFileCount
		Debug.Print(e.FileInfo.FileName)
		My.Application.DoEvents()

		dlgLogs.lsbLogs.Items.Add(e.FileInfo.FileName & " ... Extracted")

   End Sub

	Private Sub FileExists(ByVal sender As Object, ByVal e As SevenZip.FileOverwriteEventArgs)
		e.Cancel = fCancel
		If fYesAll Or Not My.Settings.ConfirmOverWrite Then Return

		dlgOverWrite.Label1.Text = String.Format("Already '{0}' exists.", Path.GetFileName(e.FileName))

		Dim _old As FileInfo = New FileInfo(e.FileName)
		dlgOverWrite.lblLengthOld.Text = String.Format("{0:#,##0} KB ({1:#,##0} Bytes)", Math.Floor(_old.Length / 1024), _old.Length)
		dlgOverWrite.lblLastWriteTimeOld.Text = String.Format("Modifid Date: {0}", _old.LastWriteTime.ToString)

		Dim efi = sze.ArchiveFileData(extractedFileCount)
		dlgOverWrite.lblLengthNew.Text = String.Format("{0:#,##0} KB ({1:#,##0} Bytes)", Math.Floor(efi.Size / 1024), efi.Size)
		dlgOverWrite.lblLastWriteTimeNew.Text = String.Format("Modifid Date: {0}", efi.LastWriteTime.ToString)

		Select Case dlgOverWrite.ShowDialog()
			Case DialogResult.Yes
				'// nothing to do
			Case DialogResult.No
				fNo = True
			Case DialogResult.OK
				fYesAll = True
			Case DialogResult.None
				fNoAll = True
			Case DialogResult.Cancel
				fCancel = True
		End Select

	End Sub

'Private Sub ExtractionFinished(ByVal sender As Object, ByVal e As SevenZip.PercentDoneEventArgs)
'Private Sub ExtractionFinished(ByVal sender As Object, ByVal e As EventArgs)
''MsgBox(e.PercentDone)
'End Sub








	''' <summary>
	''' is dlls exists? load or die.
	''' </summary>
	''' <remarks></remarks>
	Private Sub Load_7zDll()
		If File.Exists(pathTo7zDll) And File.Exists(pathTo7zs) Then
			SevenZipExtractor.SetLibraryPath(pathTo7zDll)
		Else
			MsgBox("7z.dll or SevenZipSharp.dll is not found.")
			End
		End If
	End Sub

	Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
		fCancel = True
	End Sub

End Class